
package capa_logica;

import static capa_logica.Partida.ANCHO_BOMBA;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.websocket.EncodeException;
import javax.websocket.Session;

public class Avion extends Actor
{
    private int bombas;
    private int balas;
    private Bomba b;
    private String dirActual;
    public boolean enMovimiento;
    public boolean lateral;
    public boolean lanzoBomba;
    public boolean destruiTanque1;
    public boolean destruiTanque2;
    public Session jugador1;
    public Session jugador2;
    private double centroX;
    private double centroY;
    private Piloto piloto;
    private Tanque tanque1;
    private Tanque tanque2;
    int clickX;
    int clickY;

    // Esta clase hereda de la clase ACTOR. Se utiliza para implementar lo relacionado al AVION
    public Avion(int x, int y, int ene, int vis, int vel, int lar, int anc, int ori, Escenario esc,
    Tanque t1, Tanque t2) 
    {
        super(x, y, ene, vis, vel, lar, anc, ori, esc);
        bombas = 2;
        dirActual = "derecha";
        enMovimiento = false;
        lateral = false;
        lanzoBomba = false;
        destruiTanque1 = false;
        destruiTanque2 = false;
        centroX = 0;
        centroY = 0;
        clickX = 0;
        clickY = 0;
        tanque1 = t1;
        tanque2 = t2;
    }

    public void explorar()
    {
        switch (dirActual)
        {
            case "derecha":
                /* El AVION se dirige a la derecha. */
                if (posicionX < this.e.getLargo())
                {
                    /*Puede moverse a la derecha, no se le acabo el escenario. */
                    this.posicionX = this.posicionX + this.velocidad;
                }    
                else
                {
                    this.dirActual = "izquierda";
                }
                if(lanzoBomba)
                {
                    if(b.getPosicionX() < this.e.getLargo() && (((b.getPosicionY() + ANCHO_BOMBA) < 530)))
                    {
                        b.setPosicionX(b.getPosicionX() + this.velocidad); 
                        b.setPosicionY(b.getPosicionY() + 35);
                    }
                    else
                    {
                        b.Detonar();
                        if(tanque1.getOrientacion() < 180)
                        {
                            if((b.getPosicionX() >= tanque1.getPosicionX()) && (b.getPosicionX() <= (tanque1.getPosicionX() + 179)))
                            {
                                if(tanque1.getEnergia() > 0)
                                {
                                    tanque1.eliminarActor();
                                    destruiTanque1 = true;
                                }
                            }
                        }
                        else
                        {
                            if((b.getPosicionX() >= (tanque1.getPosicionX() + 60)) && (b.getPosicionX() <= (tanque1.getPosicionX() + 179 + 60)))
                            {
                                if(tanque1.getEnergia() > 0)
                                {
                                    tanque1.eliminarActor();
                                    destruiTanque1 = true;
                                }
                            }
                        }
                        if(tanque2.getOrientacion() < 180)
                        {
                            if((b.getPosicionX() >= tanque2.getPosicionX()) && (b.getPosicionX() <= (tanque2.getPosicionX() + 179)))
                            {
                                if(tanque2.getEnergia() > 0)
                                {
                                    tanque2.eliminarActor();
                                    destruiTanque2 = true;
                                }
                            }
                        }
                        else
                        {
                            if((b.getPosicionX() >= tanque2.getPosicionX() + 60) && (b.getPosicionX() <= (tanque2.getPosicionX() + 179 + 60)))
                            {
                                if(tanque2.getEnergia() > 0)
                                {
                                    tanque2.eliminarActor();
                                    destruiTanque2 = true;
                                }
                            }
                        }
                    }
                }
                else
                {
                    b.setPosicionX((this.posicionX) + 125);
                    b.setPosicionY((this.posicionY) + 50);
                }
                break;
            case "izquierda":
                    if ((this.posicionX + largo) > 0)
                    {
                        /*Puede moverse a la derecha, no se le acabo el escenario. */
                        this.posicionX = this.posicionX - this.velocidad;
                    }
                    else
                    {
                        this.dirActual = "derecha";
                    }
                    if(lanzoBomba)
                    {
                        if((b.getPosicionX()) > 0 && ((b.getPosicionY() + ANCHO_BOMBA) < 530))
                        {
                            b.setPosicionX(b.getPosicionX() - this.velocidad); 
                            b.setPosicionY(b.getPosicionY() + 35);
                        }
                        else
                        {
                            b.Detonar();
                            if(tanque1.getOrientacion() < 180)
                            {
                                if((b.getPosicionX() >= tanque1.getPosicionX()) && (b.getPosicionX() <= (tanque1.getPosicionX() + 179)))
                                {
                                    if(tanque1.getEnergia() > 0)
                                    {
                                        tanque1.eliminarActor();
                                        destruiTanque1 = true;
                                    }
                                }
                            }
                            else
                            {
                                if((b.getPosicionX() >= (tanque1.getPosicionX() + 60)) && (b.getPosicionX() <= (tanque1.getPosicionX() + 179 + 60)))
                                {
                                    if(tanque1.getEnergia() > 0)
                                    {
                                        tanque1.eliminarActor();
                                        destruiTanque1 = true;
                                    }
                                }
                            }
                            if(tanque2.getOrientacion() < 180)
                            {
                                if((b.getPosicionX() >= tanque2.getPosicionX()) && (b.getPosicionX() <= (tanque2.getPosicionX() + 179)))
                                {
                                    if(tanque2.getEnergia() > 0)
                                    {
                                        tanque2.eliminarActor();
                                        destruiTanque2 = true;
                                    }
                                }
                            }
                            else
                            {
                                if((b.getPosicionX() >= tanque2.getPosicionX() + 60) && (b.getPosicionX() <= (tanque2.getPosicionX() + 179 + 60)))
                                {
                                    if(tanque2.getEnergia() > 0)
                                    {
                                        tanque2.eliminarActor();
                                        destruiTanque2 = true;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        b.setPosicionX((this.posicionX) + 125);
                        b.setPosicionY((this.posicionY) + 50);
                    }
                    break;
        }
    }

    public class TemporizadorAvion extends TimerTask
    {
        //Las veces que se debe repetir el código
        private int veces = 41;
        private int contadorVeces = 0;

        public void run()
        {
            contadorVeces++;
            if (contadorVeces <= veces)
            {
                /* HAY QUE PREGUNTAR QUE LA SESSION NO HAYA EXPIRADO. */
                 try
                 {
                    explorar();
                    if(lateral)
                    {
                        if(lanzoBomba)
                        {
                            if (jugador1.isOpen())
                            {
                                jugador1.getBasicRemote().
                                    sendObject(JsonBomba(b.getPosicionX(),b.getPosicionY()));
                            }
                            if (jugador2.isOpen())
                            {
                                jugador2.getBasicRemote().
                                    sendObject(JsonBomba(b.getPosicionX(),b.getPosicionY()));
                            }
                        }
                        if (jugador1.isOpen())
                        {
                            jugador1.getBasicRemote().
                                sendObject(JsonAvionLateral(posicionX,posicionY));
                        }
                        if (jugador2.isOpen())
                        {
                            jugador2.getBasicRemote().
                                sendObject(JsonAvionLateral(posicionX,posicionY));
                        }
                    }
                    else
                    {
                        
                        if (jugador1.isOpen())
                        {
                            jugador1.getBasicRemote().
                                sendObject(JsonAvion(posicionX,posicionY));
                            jugador1.getBasicRemote().
                                sendObject(JsonIluminarAvion(posicionX,posicionY));
                            jugador1.getBasicRemote().
                                sendObject(visibilidadAvion());
                        }
                        if (jugador2.isOpen())
                        {
                            jugador2.getBasicRemote().
                                sendObject(JsonAvion(posicionX,posicionY));
                        }
                    }
                }
                catch (IOException ex)
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                }
                catch (EncodeException ex)
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            else
            {
                this.cancel();
                enMovimiento = false;
                lanzoBomba = false;
                try
                {
                    jugador1.getBasicRemote().sendObject(JsonRestarurarSombra());
                    if(lateral)
                    {
                        lateral = false;
                        jugador1.getBasicRemote().sendObject(JsonTerminarLateral());
                        jugador2.getBasicRemote().sendObject(JsonTerminarLateral());
                        if(destruiTanque1)
                        {
                            jugador1.getBasicRemote().sendObject(JsonDestruirTanque(1));
                            jugador2.getBasicRemote().sendObject(JsonDestruirTanque(1));
                        }
                        if(destruiTanque2)
                        {
                            jugador1.getBasicRemote().sendObject(JsonDestruirTanque(2));
                            jugador2.getBasicRemote().sendObject(JsonDestruirTanque(2));
                        }
                    }
                }
                catch (IOException ex)
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                } 
                catch (EncodeException ex) 
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }
       
    public void LanzarAvion(boolean lateral)
    {
        if(!enMovimiento)
        {
            enMovimiento = true;
            if(dirActual=="derecha")
            {
                orientacion = 90;
                this.posicionX = 0 - largo;
            }
            else
            {
                orientacion = 270;
                this.posicionX= e.getLargo();
            }

            this.posicionY = clickY - (ancho / 2);
            b = new Bomba(this.posicionX,this.posicionY);
            Timer temporizador = new Timer("");
            Avion.TemporizadorAvion temp;
            temp = new Avion.TemporizadorAvion();
            this.lateral = lateral;
            if(this.lateral)
            {
                temp.veces=41;
                posicionY = 60;
            }
            else
            {
                try
                {
                    jugador1.getBasicRemote().sendObject(JsonGuardarSombra());
                }
                catch (IOException ex)
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                }
                catch (EncodeException ex)
                {
                    Logger.getLogger(Avion.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            temporizador.schedule(temp, 100, 100);
        }
    }
    
    public JsonObject JsonGuardarSombra()
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "guardarSombra");
        JsonObject value = buildJson.build();
        return value;
    }
    
    public JsonObject JsonRestarurarSombra()
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "restaurarSombra");
        JsonObject value = buildJson.build();
        return value;
    }
    
    public JsonObject JsonAvion(int x, int y)
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "avion");
        buildJson = buildJson.add("avionX", x);
        buildJson = buildJson.add("avionY", y);
        buildJson = buildJson.add("orientacionAvion", this.orientacion);
        JsonObject value = buildJson.build();
        return value;
    }
    
    public JsonObject JsonAvionLateral(int x, int y)
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "avionLateral");
        buildJson = buildJson.add("avionX", x);
        buildJson = buildJson.add("avionY", y);
        buildJson = buildJson.add("orientacionAvion", this.orientacion);
        JsonObject value = buildJson.build();
        return value;
    }
    
    public JsonObject JsonBomba(int x, int y)
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "lanzarBomba");
        buildJson = buildJson.add("bombaX", x);
        buildJson = buildJson.add("bombaY", y);
        buildJson = buildJson.add("orientacion", this.orientacion);
        buildJson = buildJson.add("detonar", b.getDetonar());
        JsonObject value = buildJson.build();
        return value;
    }
    public JsonObject JsonTerminarLateral()
    {
        JsonObject value;
        if(destruiTanque1 && destruiTanque2)
        {
            JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "finalizarJuego");
            buildJson = buildJson.add("jugadorGanador", "jugador1");
            value = buildJson.build();
        }
        else
        {
            JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "terminarLateral");
            value = buildJson.build();
        }
        return value;
    }
    
    public JsonObject JsonDestruirTanque(int tanque)
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "destruirTanque");
        if(tanque == 1)
        {
            buildJson = buildJson.add("tanque", 1);
            buildJson = buildJson.add("posX", tanque1.getPosicionX());
            buildJson = buildJson.add("posY", tanque1.getPosicionY());
            buildJson = buildJson.add("orientacion", tanque1.getOrientacion());
        }
        else
        {
            buildJson = buildJson.add("tanque", 2);
            buildJson = buildJson.add("posX", tanque2.getPosicionX());
            buildJson = buildJson.add("posY", tanque2.getPosicionY());
            buildJson = buildJson.add("orientacion", tanque2.getOrientacion());
        }
        JsonObject value = buildJson.build();
        return value;
    }
    
    public JsonObject JsonIluminarAvion(int x, int y)
    {
        JsonObjectBuilder buildJson = Json.createObjectBuilder().add("orden", "iluminarAvion");
        buildJson = buildJson.add("avionX", x);
        buildJson = buildJson.add("avionY", y);
        JsonObject value = buildJson.build();
        return value;
    }
    
     public boolean avionVeTanqueN(int numeroTanque)
    {
        int or1 = tanque1.getOrientacion();
        int or2 = tanque2.getOrientacion();
        int xCentroTanque = 0; 
        int yCentroTanque = 0;
        int xCentroAvion = this.posicionX + this.ancho / 2;
        int yCentroAvion = this.posicionY + this.largo / 2;

        int radioTanque = 0; //Correctivo para la visibilidad.


        if (numeroTanque == 1)
        {
            xCentroTanque = Utilidades.darCentroX(tanque1.getPosicionX(), or1);
            yCentroTanque = Utilidades.darCentroY(tanque1.getPosicionY(), or1);
            radioTanque = this.tanque1.getAncho() / 2;
        }
        else
        {
            xCentroTanque = Utilidades.darCentroX(tanque2.getPosicionX(), or2);
            yCentroTanque = Utilidades.darCentroY(tanque2.getPosicionY(), or2);
            radioTanque = this.tanque2.getAncho() / 2;
        }
                                    
        return true;
    }
     
    public JsonObject visibilidadAvion()
    {
           JsonObjectBuilder construirJson = Json.createObjectBuilder().add("orden", "visibilidadAvion");
           construirJson = construirJson.add("avionVeTanque1", avionVeTanqueN(1));
           construirJson = construirJson.add("avionVeTanque2", avionVeTanqueN(2));
           JsonObject jsonJugador = construirJson.build();
           return jsonJugador;
    }
    
    // Getters y Setters
    
    public boolean isEnMovimiento() {
        return enMovimiento;
    }

    public void setEnMovimiento(boolean enMovimiento) {
        this.enMovimiento = enMovimiento;
    }
    
    public boolean isLanzoBomba()
    {
        return lanzoBomba;
    }
    
    public Bomba getB()
    {
        return b;
    }

    public void setLanzoBomba(boolean lanzoBomba) {
        this.lanzoBomba = lanzoBomba;
    }
        
    public boolean isLateral()
    {
        return lateral;
    }
        
    public int getBombas() {
        return bombas;
    }

    public void setBombas(int bombas) {
        this.bombas = bombas;
    }

    public int getBalas() {
        return balas;
    }

    public void setBalas(int balas) {
        this.balas = balas;
    }
    
    public int getClickX() {
        return clickX;
    }

    public void setClickX(int clickX) {
        this.clickX = clickX;
    }

    public int getClickY() {
        return clickY;
    }

    public void setClickY(int clickY) {
        this.clickY = clickY;
    }

    public void setTanque1(Tanque tanque1) {
        this.tanque1 = tanque1;
    }

    public void setTanque2(Tanque tanque2) {
        this.tanque2 = tanque2;
    }
}